package com.vogue.flowmeter.ui.activity;

import android.Manifest;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatTextView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.maning.mndialoglibrary.MProgressDialog;
import com.tbruyelle.rxpermissions2.RxPermissions;
import com.vogue.flowmeter.R;
import com.vogue.flowmeter.api.entity.ApiUpdateHexEntity;
import com.vogue.flowmeter.api.entity.BaseResponse;
import com.vogue.flowmeter.api.event.DownloadMessageEvent;
import com.vogue.flowmeter.api.event.MessageUpdateEvent;
import com.vogue.flowmeter.api.event.RecordMessageEvent;
import com.vogue.flowmeter.api.retrofit.NetWorkManager;
import com.vogue.flowmeter.profile.BleProfileService;
import com.vogue.flowmeter.profile.data.VogueBleWriteData;
import com.vogue.flowmeter.ui.fragment.DashboardFragment;
import com.vogue.flowmeter.update.BgUpdate;
import com.vogue.flowmeter.util.ConvertUtils;
import com.vogue.flowmeter.util.FileUtils;
import com.vogue.flowmeter.util.PrefsUtils;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.observers.DefaultObserver;
import io.reactivex.schedulers.Schedulers;
import no.nordicsemi.android.ble.common.util.CRC16;
import okhttp3.ResponseBody;

/**
 * hex升级
 */
public class UpdateHexActivity extends AppCompatActivity {

    @BindView(R.id.tv_file_name)
    AppCompatTextView tvFileName;
    @BindView(R.id.tv_file_type)
    AppCompatTextView tvFileType;
    @BindView(R.id.tv_file_size)
    AppCompatTextView tvFileSize;
    @BindView(R.id.tv_file_version)
    AppCompatTextView tvFileVersion;
    @BindView(R.id.tv_file_status)
    AppCompatTextView tvFileStatus;
    @BindView(R.id.tv_file_no_load)
    AppCompatTextView tvFileNoLoad;
    @BindView(R.id.btn_start_update)
    Button btnStartUpdate;
    @BindView(R.id.lay_synchronization_file)
    LinearLayout laySynchronizationFile;
    @BindView(R.id.btn_synchronization_file)
    Button btnSynchronizationFile;

    private ProgressDialog mProgressDialog;

    private ApiUpdateHexEntity update;
    private String upgradeChoose = "";
    protected BleProfileService.LocalBinder localBinder;
    protected static int OVERLAY_PERMISSION_REQ_CODE = 110;


    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            localBinder = (BleProfileService.LocalBinder) service;
            Log.e(UpdateHexActivity.class.getName(), "serviceConnection");
            if (localBinder.isReady()) {
                showToast("设备已就绪");
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent = new Intent(UpdateHexActivity.this, BleProfileService.class);
        bindService(intent, serviceConnection, BIND_AUTO_CREATE);
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this);
        }
        setContentView(R.layout.activity_update_hex);
        ButterKnife.bind(this);
        ActionBar actionBar=getSupportActionBar();
        if(actionBar != null){
            actionBar.setHomeButtonEnabled(true);
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
        setTitle("蓝牙(HEX)更新");

        btnStartUpdate.setVisibility(View.GONE);
        tvFileNoLoad.setVisibility(View.VISIBLE);
        laySynchronizationFile.setVisibility(View.VISIBLE);
        final Intent upgrade = getIntent();
        if ("master".equals(upgrade.getCharSequenceExtra("upgrade"))) {
            upgradeChoose = "master";
        }
        if ("slave".equals(upgrade.getCharSequenceExtra("upgrade"))) {
            upgradeChoose = "slave";
        }
        if (TextUtils.isEmpty(upgradeChoose)) {
            upgradeChoose = "master";
        }

        //初始化进度对话框
        mProgressDialog = new ProgressDialog(this);
        //8.0系统加强后台管理，禁止在其他应用和窗口弹提醒弹窗，如果要弹，必须使用TYPE_APPLICATION_OVERLAY，否则弹不出
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            mProgressDialog.getWindow().setType((WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY));
        } else {
            mProgressDialog.getWindow().setType((WindowManager.LayoutParams.TYPE_SYSTEM_ALERT));
        }
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);// 设置水平进度条
        //重置hexCode
        PrefsUtils.getInstance(UpdateHexActivity.this).putInt("hexCode", 0);
        String hexLocalFilePath = PrefsUtils.getInstance(UpdateHexActivity.this).get("hexLocalFilePath", "");
        if (FileUtils.fileExists(hexLocalFilePath)) {
            FileUtils.deleteFile(new File(hexLocalFilePath));
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                this.finish(); // back button
                return true;
        }
        return super.onOptionsItemSelected(item);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this);
        }
        unbindService(serviceConnection);
    }

    /**
     * 同步文件，从服务器上下载
     */
    private void onSynchronizationFileClicked() {
        //发送事件出去
        RecordMessageEvent recordMessageEvent = new RecordMessageEvent("onSynchronizationFileClicked", "同步文件，从服务器上下载");
        EventBus.getDefault().post(recordMessageEvent);
        RxPermissions rxPermissions = new RxPermissions(UpdateHexActivity.this);
        rxPermissions.request(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE, Manifest.permission.INTERNET).subscribe(aBoolean -> {
            if (aBoolean) {

                ApiUpdateHexEntity updateHex = new ApiUpdateHexEntity();
                int code = PrefsUtils.getInstance(UpdateHexActivity.this).getInt("hexCode", 0);//取本地存储的版本
                updateHex.setCode(code);//传回当前版本

                NetWorkManager
                        .getInstance()
                        .getBleApiService()
                        .getUpdateHex(updateHex)
                        .subscribeOn(Schedulers.io())
                        .doOnSubscribe(disposable -> {
                            MProgressDialog.showProgress(UpdateHexActivity.this, "加载中...");
                        })
                        .subscribeOn(AndroidSchedulers.mainThread())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new DefaultObserver<ResponseBody>() {
                            @Override
                            public void onNext(ResponseBody response) {
                                MProgressDialog.dismissProgress();
                                try {
                                    String body = response.string();
                                    BaseResponse<ApiUpdateHexEntity> res = JSON.parseObject(body, new TypeReference<BaseResponse<ApiUpdateHexEntity>>(ApiUpdateHexEntity.class) {
                                    });
                                    if (res.getCode() == 0 && res.getData() != null) {
                                        //储存HEXcode待下次更新取值
                                        update = res.getData();
                                        if (FileUtils.isSdCardAvailable()) {

                                            String filePath = FileUtils.getDataPath(getApplicationContext());
                                            int hexCode = PrefsUtils.getInstance(UpdateHexActivity.this).getInt("hexCode", 0);

                                            if (FileUtils.fileExists(filePath + "/" + update.getFileName()) && hexCode == update.getCode()) {

                                                tvFileName.setText(update.getFileName());
                                                tvFileType.setText("HEX");
                                                tvFileSize.setText(FileUtils.formatFileSizeToString(new File(filePath + "/" + update.getFileName()).length()));
                                                tvFileVersion.setText(update.getVersion());
                                                tvFileStatus.setText("已加载");

                                                btnStartUpdate.setVisibility(View.VISIBLE);
                                                tvFileNoLoad.setVisibility(View.GONE);
                                                laySynchronizationFile.setVisibility(View.GONE);

                                            } else {
                                                BgUpdate.downloadForUpdate(UpdateHexActivity.this, res.getData().getFileUrl(), filePath, res.getData().getFileName(), false);
                                            }
                                        }
                                    } else {
                                        String hexLocalFilePath = PrefsUtils.getInstance(UpdateHexActivity.this).get("hexLocalFilePath", "");
                                        if (FileUtils.fileExists(hexLocalFilePath)) {

                                            String FileName = PrefsUtils.getInstance(UpdateHexActivity.this).get("FileName", "");
                                            String FileVersion = PrefsUtils.getInstance(UpdateHexActivity.this).get("FileVersion", "");

                                            tvFileName.setText(FileName);
                                            tvFileType.setText("HEX");
                                            tvFileSize.setText(FileUtils.formatFileSizeToString(new File(hexLocalFilePath).length()));
                                            tvFileVersion.setText(FileVersion);
                                            tvFileStatus.setText("已加载");

                                            btnStartUpdate.setVisibility(View.VISIBLE);
                                            tvFileNoLoad.setVisibility(View.GONE);
                                            laySynchronizationFile.setVisibility(View.GONE);

                                        } else {
                                            Toast.makeText(UpdateHexActivity.this, "服务器上没有找到文件", Toast.LENGTH_LONG).show();
                                            Log.e(UpdateHexActivity.class.getName(), "服务器上没有找到文件");
                                        }

                                    }
                                } catch (IOException i) {
                                    showToast(i.getMessage());
                                }
                            }

                            @Override
                            public void onError(Throwable e) {
                                MProgressDialog.dismissProgress();
                                showToast("同步请求出错");
                            }

                            @Override
                            public void onComplete() {
                                MProgressDialog.dismissProgress();
                            }
                        });
            }

        });

    }

    public void onHelpClicked(final View view) {
        //发送事件出去
        RecordMessageEvent recordMessageEvent = new RecordMessageEvent("onHelpClicked", "查看帮助");
        EventBus.getDefault().post(recordMessageEvent);
        new AlertDialog.Builder(this)
                .setTitle(R.string.dfu_help_title)
                .setMessage(R.string.dfu_help_message)
                .setPositiveButton("确定", null)
                .show();
    }


    /**
     * 订阅消息  更新进度
     *
     * @param event
     */
    @Subscribe
    public void onUpdateMessageEvent(MessageUpdateEvent event) {
        Log.e(DashboardFragment.class.getName(), event.toString());

        if (event.getLine() == event.getLines() &&event.getProgress() == 100) {
            if (mProgressDialog.isShowing()) {
                mProgressDialog.setProgress(100);
                mProgressDialog.dismiss();

            }
            new AlertDialog.Builder(this)
                    .setTitle("上传已完成")
                    .setMessage("点击确定回到首页去吧")
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            finish();
                        }
                    })
                    .show();
        }else {
            mProgressDialog.setTitle("更新进度");
            mProgressDialog.setProgress(event.getProgress());
            if (!mProgressDialog.isShowing())
                mProgressDialog.show();
        }
    }

    /**
     * 订阅消息 下载完成
     *
     * @param event
     */
    @Subscribe
    public void onDownloadMessageEvent(DownloadMessageEvent event) {
        Log.e(DashboardFragment.class.getName(), event.getMessage());

        if (event.getProgress() >= 100 && event.isStatus()) {
            if (mProgressDialog.isShowing()) {
                mProgressDialog.setProgress(100);
                mProgressDialog.dismiss();
            }
            mProgressDialog.dismiss();
            if (!event.isApk()) {
                String filePath = FileUtils.getDataPath(getApplicationContext());

                PrefsUtils.getInstance(UpdateHexActivity.this).put("hexLocalFilePath", filePath + "/" + update.getFileName());
                PrefsUtils.getInstance(UpdateHexActivity.this).putInt("hexCode", update.getCode());

                PrefsUtils.getInstance(UpdateHexActivity.this).put("FileName", update.getFileName());
                PrefsUtils.getInstance(UpdateHexActivity.this).put("FileVersion", update.getVersion());

                tvFileName.setText(update.getFileName());
                tvFileType.setText("HEX");
                tvFileSize.setText(FileUtils.formatFileSizeToString(new File(filePath + "/" + update.getFileName()).length()));
                tvFileVersion.setText(update.getVersion());
                tvFileStatus.setText("已加载");

                btnStartUpdate.setVisibility(View.VISIBLE);
                tvFileNoLoad.setVisibility(View.GONE);
                laySynchronizationFile.setVisibility(View.GONE);

            }

        } else {
            mProgressDialog.setTitle("下载进度");
            mProgressDialog.setProgress(event.getProgress());
            if (!mProgressDialog.isShowing())
                mProgressDialog.show();
        }

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
            if (Build.VERSION.SDK_INT >= 23) {
                if (!Settings.canDrawOverlays(this)) {
                    Toast.makeText(this, "权限授予失败，无法开启悬浮窗", Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(this, "悬浮弹窗权限授予成功！", Toast.LENGTH_LONG).show();
                }
            }
        }
    }
    @OnClick({R.id.btn_start_update,R.id.btn_synchronization_file})
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_synchronization_file:
                if (Build.VERSION.SDK_INT >= 23) {
                    if (Settings.canDrawOverlays(this)) {
                        onSynchronizationFileClicked();
                    } else {
                        new AlertDialog.Builder(this)
                                .setTitle("授权提醒")
                                .setMessage("没有悬浮窗权限,去开启悬浮窗权限")
                                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
                                        intent.setData(Uri.parse("package:" + getPackageName()));
                                        startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
                                    }
                                })
                                .show();
                    }
                } else {
                    onSynchronizationFileClicked();
                }
                break;
            case R.id.btn_start_update:
                if (Build.VERSION.SDK_INT >= 23) {
                    if (Settings.canDrawOverlays(this)) {
                        onUpdateData();
                    } else {
                        new AlertDialog.Builder(this)
                                .setTitle("授权提醒")
                                .setMessage("没有悬浮窗权限,去开启悬浮窗权限")
                                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
                                        intent.setData(Uri.parse("package:" + getPackageName()));
                                        startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
                                    }
                                })
                                .show();
                    }
                } else {
                    onUpdateData();
                }
                break;

        }

    }

    /**
     * 向蓝牙设备更新hex包
     */
    private void onUpdateData() {
        //发送事件出去
        RecordMessageEvent recordMessageEvent = new RecordMessageEvent("StartUpdate", "点击开始更新");
        EventBus.getDefault().post(recordMessageEvent);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                RxPermissions rxPermissions = new RxPermissions(UpdateHexActivity.this);
                rxPermissions.request(Manifest.permission.READ_EXTERNAL_STORAGE).subscribe(aBoolean -> {
                    if (aBoolean) {
                        try {
                            String hexLocalFilePath = PrefsUtils.getInstance(UpdateHexActivity.this).get("hexLocalFilePath", "");
                            if (!FileUtils.fileExists(hexLocalFilePath)) {
                                showToast("没有找到文件");
                                return;
                            }
                            File file = new File(hexLocalFilePath);
                            LineNumberReader lineNumberReader = new LineNumberReader(new FileReader(file));
                            lineNumberReader.skip(Long.MAX_VALUE);
                            BufferedReader reader = new BufferedReader(new FileReader(file));

                            int lines = lineNumberReader.getLineNumber();
                            Log.e(UpdateHexActivity.class.getName(), "总行数：" + lines);

                            String readLine = null;
                            int line = 0;
                            while ((readLine = reader.readLine()) != null) {
                                readLine = "3a" + readLine.substring(1, readLine.length());
                                line++;

                                Log.e(UpdateHexActivity.class.getName(), "CRC16：" + ConvertUtils.numToHex16(CRC16.AUG_CCITT(readLine.getBytes(), 0, readLine.length())));
                                String data = ConvertUtils.numToHex16(Integer.valueOf(line)) + ConvertUtils.numToHex16(lines) + readLine + ConvertUtils.numToHex16(CRC16.AUG_CCITT(readLine.getBytes(), 0, readLine.length()));
                                if (localBinder.isReady()) {
                                    if ("master".equals(upgradeChoose)) {
                                        localBinder.write(VogueBleWriteData.MasterEquipmentUpgrade(data));
                                    } else {
                                        localBinder.write(VogueBleWriteData.SlaveEquipmentUpgrade(data));
                                    }
                                }

                                int progress = (int) (Math.floor((line / (double) lines) * 100));
                                Log.e(UpdateHexActivity.class.getName(), "进度：" + progress + "% ===" + line + "====" + readLine);
                                //演示 读指定的行数  正式的环境删除
                                /*if (line > 1000) {
                                    mProgressDialog.dismiss();
                                    break;
                                }*/
                            }
                        } catch (IOException i) {

                        }
                    }
                });
            }
        });
    }

    /**
     * @param msg
     */
    protected void showToast(String msg) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(UpdateHexActivity.this, msg, Toast.LENGTH_LONG).show();
            }
        });
    }


}